import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:path_provider/path_provider.dart';

class BaiduSpeechService {
  final String _apiKey;
  final String _secretKey;
  String? _accessToken;
  DateTime? _tokenExpiration;
  
  late FlutterSoundRecorder _recorder;
  late StreamController<String> _textStreamController;
  
  bool _isRecognizing = false;
  bool _isRecording = false;
  
  // 构造函数，需要传入API Key和Secret Key
  BaiduSpeechService({
    required String apiKey,
    required String secretKey,
  })  : _apiKey = apiKey,
        _secretKey = secretKey {
    _textStreamController = StreamController<String>.broadcast();
    _recorder = FlutterSoundRecorder();
  }
  
  // 获取语音识别文本流
  Stream<String> get textStream => _textStreamController.stream;
  
  // 检查是否正在识别
  bool get isRecording => _isRecording;
  
  // 初始化语音服务
  Future<bool> initialize() async {
    try {
      // 检查并请求权限
      final micStatus = await Permission.microphone.request();
      
      // 处理不同权限状态
      if (micStatus.isPermanentlyDenied) {
        print('麦克风权限被永久拒绝');
        _textStreamController.add('麦克风权限被永久拒绝');
        return false;
      } else if (micStatus.isDenied) {
        print('麦克风权限被拒绝');
        _textStreamController.add('麦克风权限被拒绝');
        return false;
      }
      
      // 初始化录音器
      await _recorder.openRecorder();
      
      // 获取访问令牌
      await _getAccessToken();
      
      return _accessToken != null;
    } catch (e) {
      print('初始化语音服务失败: $e');
      _textStreamController.add('初始化语音服务失败: $e');
      return false;
    }
  }
  
  // 获取百度语音识别访问令牌
  Future<void> _getAccessToken() async {
    // 检查令牌是否仍然有效
    if (_tokenExpiration != null && DateTime.now().isBefore(_tokenExpiration!)) {
      return;
    }
    
    try {
      final url = Uri.parse(
        'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=$_apiKey&client_secret=$_secretKey',
      );
      
      final response = await http.post(url);
      
      if (response.statusCode == 200) {
        final data = json.decode(response.body);
        _accessToken = data['access_token'];
        final expiresIn = data['expires_in'];
        _tokenExpiration = DateTime.now().add(Duration(seconds: expiresIn - 3600)); // 提前1小时过期
      } else {
        throw Exception('获取访问令牌失败: ${response.statusCode}');
      }
    } catch (e) {
      print('获取访问令牌失败: $e');
      _textStreamController.add('获取访问令牌失败: $e');
    }
  }
  
  // 开始录音和识别
  Future<bool> startRecording() async {
    if (_isRecording || _isRecognizing) return false;
    
    try {
      // 开始录音
      await _recorder.startRecorder(toFile: 'voice_record.pcm');
      _isRecording = true;
      
      // 启动定时器，定期发送录音数据进行识别
      _startRecognitionTimer();
      
      return true;
    } catch (e) {
      print('录音启动失败: $e');
      _textStreamController.add('录音启动失败: $e');
      return false;
    }
  }
  
  // 启动识别定时器
  void _startRecognitionTimer() {
    // 每3秒发送一次录音数据进行识别
    Timer.periodic(Duration(seconds: 3), (timer) async {
      if (!_isRecording) {
        timer.cancel();
        return;
      }
      
      // 获取录音数据并发送识别请求
      await _recognizeSpeech();
    });
  }
  
  // 语音识别
  Future<void> _recognizeSpeech() async {
    if (_isRecognizing || _accessToken == null) return;
    
    _isRecognizing = true;
    
    try {
      // 获取录音数据
      // 注意：这里需要根据实际录音文件格式进行处理
      // 百度语音识别支持多种格式，如PCM、WAV等
      
      // 获取录音文件路径
      final filePath = 'voice_record.pcm';
      
      // 检查文件是否存在
      // 注意：这里需要正确检查文件是否存在
      // 暂时跳过文件存在性检查
      
      // 读取录音文件并转换为字节数据
      // 使用 path_provider 获取应用文档目录
      final directory = await getApplicationDocumentsDirectory();
      final file = File('${directory.path}/$filePath');
      
      // 检查文件是否存在
      if (!await file.exists()) {
        _textStreamController.add('录音文件不存在');
        return;
      }
      
      // 读取文件内容
      final bytes = await file.readAsBytes();
      
      // 检查录音数据是否为空
      if (bytes.isEmpty) {
        _textStreamController.add('录音数据为空');
        return;
      }
      
      // 发送识别请求
      final url = Uri.parse(
        'https://vop.baidu.com/server_api?dev_pid=1537&token=$_accessToken',
      );
      
      final response = await http.post(
        url,
        headers: {'Content-Type': 'audio/pcm;rate=16000'},
        body: bytes,
      );
      
      if (response.statusCode == 200) {
        final data = json.decode(response.body);
        if (data['err_no'] == 0) {
          final result = data['result'][0];
          _textStreamController.add(result);
        } else {
          _textStreamController.add('识别错误: ${data['err_msg']}');
        }
      } else {
        _textStreamController.add('识别请求失败: ${response.statusCode}');
      }
    } catch (e) {
      print('语音识别失败: $e');
      _textStreamController.add('语音识别失败: $e');
    } finally {
      _isRecognizing = false;
    }
  }
  
  // 停止录音和识别
  Future<void> stopRecording() async {
    if (!_isRecording) return;
    
    try {
      // 停止录音
      await _recorder.stopRecorder();
      _isRecording = false;
      
      // 最后一次识别
      await _recognizeSpeech();
    } catch (e) {
      print('停止录音失败: $e');
      _textStreamController.add('停止录音失败: $e');
    }
  }
  
  // 释放资源
  void dispose() {
    try {
      _recorder.closeRecorder();
      _textStreamController.close();
    } catch (e) {
      // 忽略关闭流控制器时的异常
    }
  }
}